<!-- <template>
  <div id="my-three"></div>
</template> -->
<template>
    <div>
      <div class="ls_maincont"></div>
      <div id="my-three" ref="environment" style="position: absolute; top: 0"></div>
      <div class="stage_t">
        <div class="stage_t_left">  
            <img src="../assets/logins.jpg" alt=""> <span>国能怀安热电有限公司</span>
       </div>
       <div  class="stage_t_zhong">燃烧数字化监测与可视化系统</div>
       <div  class="stage_t_right">
           <img src="../assets/timer.png" alt=""> <span>{{ nowTime }}</span>
       </div>
      </div>
      <div class="stage_c_l">
        <div class="t">
          <div class="wendutiao_react"></div>
          <div class="wendutiao_text">
            <span style="color: white;">1620</span>
            <span style="color: white;">1450</span>
            <span style="color: white;">1270</span>
            <span style="color: white;">1090</span>
            <span style="color: white;">910</span>
            <span style="color: white;">730</span>
            <span style="color: white;">560</span>
            <span style="color: white;">380</span>
            <span style="color: white;">204</span>
          </div>
        </div>
        <div class="d">°C</div>
      </div>
  
      <!-- <div class="stage_c_r">
        <div class="t">
          <div class="react">
            <i class="l_up"></i>
            <i class="l_down"></i>
            <i class="r_up"></i>
            <i class="r_down"></i>
            <div class="title">
              <span style="font-size: 29px">横截面温度分布</span>
            </div>
          </div>
        </div>
        <div class="d" id="zbf_r_btns" style="flex: 1">
          <span class="active" @click="handleClick('S', $event)">燃尽风层截面</span>
          <span class="active" @click="handleClick('E', $event)">E层燃烧器截面</span>
          <span class="active" @click="handleClick('D', $event)">D层燃烧器截面</span>
          <span class="active" @click="handleClick('C', $event)">C层燃烧器截面</span>
          <span class="active" @click="handleClick('B', $event)">B层燃烧器截面</span>
          <span class="active" @click="handleClick('A', $event)">A层燃烧器截面</span>
          <span @click="handleFireClick($event)">火焰状态</span>
          <span isclose="false" @click="handleClickAll($event)">全部关闭</span>
        </div>
      </div> -->
    </div>
  </template>
  <script setup>
  import { ref, onMounted, computed, reactive, watch } from "vue";
  import * as THREE from "three";
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //gltf
  import { formatTime } from "../utils/date.js";
  import * as TWEEN from '@tweenjs/tween.js'
  import flamex from "../assets/flamex.png"
  
  
  
  // const {proxy} = getCurrentInstance();
  onMounted(() => {
    setInterval(() => {
      nowTime.value = formatTime(new Date());
    });
    document.getElementById("my-three")?.appendChild(renderer.domElement);
    init();
    renderModel();
    gltfModel1();
    render();
    renderFires()
  });
  
  let runcaizhi = ref("");
  let stopcaizhi = ref("");
  let touming = ref("");
  const nowTime = ref("");
  const width = window.innerWidth,
    height = window.innerHeight;
  const scene = new THREE.Scene();
  const renderer = new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true, alpha: true });
  const loader = new GLTFLoader();
  const camera = new THREE.PerspectiveCamera(25, width / height, 0.1, 1000);
  const controls = new OrbitControls(camera, renderer.domElement);
  
  function init() {
    //光源#9e9e9e
    const ambient = new THREE.AmbientLight(0xffffff, 0.4);
    scene.add(ambient);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); //光源，color:灯光颜色，intensity:光照强度
    directionalLight.position.set(25, 150, 75);
    scene.add(directionalLight);
    //设置相机位置
    camera.position.set(-8, 5, 30);
    //设置相机方向
    camera.lookAt(0, -5, 0);
    controls.target.set(0, -5, 0);
  
    // scene.background = new THREE.Color(0x9e9e9e);
    renderer.setPixelRatio(window.devicePixelRatio);
    // renderer.antialias = true;
    // renderer.shadowMap.enabled = true;
    // renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    // renderer.setDepthTest(true);
  }
  
  const modelObj = {}; // 模型对象函数
  
  
  /**
   * 粒子 延迟发散
   * @param particle
   * @param delay
   */
  let tweenArr = []
  function initParticle(particle, delay) {
    particle.position.set(5, Math.random() + 5, 0);
    particle.scale.x = particle.scale.y = Math.random() * 3;
    //下面是一系列的动画
    var xx = Math.random() * 10 - 5;
    var yy = Math.cos((Math.PI / 100) * xx) * 21;
    //位移
    let tween1 = new TWEEN.Tween(particle.position)
      .delay(delay)
      .to({
        x: xx,
        y: yy,
        z: Math.random() * 10 - 5
      }, 2000)
      .onComplete(function () {
        initParticle(particle, delay);
      })
      .start();
    // 大小
    let tween2 = new TWEEN.Tween(particle.scale)
      .delay(delay)
      .to({
        x: 0.01,
        y: 0.01
      }, 900)
      .start();
    tweenArr.push(tween1)
    tweenArr.push(tween2)
    return particle
  }
  
  
  const fireGroup = new THREE.Group()
  // 火焰状态点击处理函数
  const handleFireClick = function (e) {
    if (e.currentTarget.classList.length === 1) {
      e.currentTarget.classList.remove("active");
      tweenArr.forEach(item => {
        item.stop()
      })
      tweenArr = []
      fireGroup.clear()
    } else {
      e.currentTarget.classList.add("active");
      renderFires()
    }
  }
  let guoluScene
  // 生成并渲染火焰
  const renderFires = function () {
    new THREE.TextureLoader().load(flamex, texture => {
      //sprite材质
      var material = new THREE.SpriteMaterial({
        map: texture,
        blending: THREE.AdditiveBlending, //混合度 减法混合
        color: 0xffffff,
        // depthTest: false,
        depthWrite: false,
        fog: true
      });
      const fireA1 = new THREE.Object3D();
      const fireA2 = new THREE.Object3D();
      console.log(fireA2);
      const fireA3 = new THREE.Object3D();
      const fireA4 = new THREE.Object3D();
      const fireB1 = new THREE.Object3D();
      const fireB2 = new THREE.Object3D();
      const fireB3 = new THREE.Object3D();
      const fireB4 = new THREE.Object3D();
      const fireC1 = new THREE.Object3D();
      const fireC2 = new THREE.Object3D();
      const fireC3 = new THREE.Object3D();
      const fireC4 = new THREE.Object3D();
      const fireD1 = new THREE.Object3D();
      const fireD2 = new THREE.Object3D();
      const fireD3 = new THREE.Object3D();
      const fireD4 = new THREE.Object3D();
      const fireE1 = new THREE.Object3D();
      const fireE2 = new THREE.Object3D();
      const fireE3 = new THREE.Object3D();
      const fireE4 = new THREE.Object3D();
      for (var i = 0; i < 800; i++) {
        fireA1.add(initParticle(new THREE.Sprite(material), i))
        fireA2.add(initParticle(new THREE.Sprite(material), i))
        fireA3.add(initParticle(new THREE.Sprite(material), i))
        fireA4.add(initParticle(new THREE.Sprite(material), i))
        fireB1.add(initParticle(new THREE.Sprite(material), i))
        fireB2.add(initParticle(new THREE.Sprite(material), i))
        fireB3.add(initParticle(new THREE.Sprite(material), i))
        fireB4.add(initParticle(new THREE.Sprite(material), i))
        fireC1.add(initParticle(new THREE.Sprite(material), i))
        fireC2.add(initParticle(new THREE.Sprite(material), i))
        fireC3.add(initParticle(new THREE.Sprite(material), i))
        fireC4.add(initParticle(new THREE.Sprite(material), i))
        fireD1.add(initParticle(new THREE.Sprite(material), i))
        fireD2.add(initParticle(new THREE.Sprite(material), i))
        fireD3.add(initParticle(new THREE.Sprite(material), i))
        fireD4.add(initParticle(new THREE.Sprite(material), i))
      }
      fireA1.name = "fireA1"
    fireA1.position.set(3.62, 10.47, 0.28);
    fireA1.rotation.set(0, 0, 1);
    fireA1.scale.set(0.54, 0.54, 1);
      fireA2.name = "fireA2"
      fireA2.position.set(-0.99, -6, -1);
      fireA2.rotation.set(0, -10.56, 1);
      fireA2.scale.set(0.3, 0.25, 0.2);
      fireA3.name = "fireA3"
      fireA3.position.set(-0.93, -6, 1);
      fireA3.rotation.set(0, 3.75, 1);
      fireA3.scale.set(0.3, 0.25, 0.2);
      fireA4.name = "fireA4"
      fireA4.position.set(1, -6, 1);
      fireA4.rotation.set(0, -0.8, 1);
      fireA4.scale.set(0.3, 0.25, 0.2);
  
      fireB1.name = "fireB1"
      fireB1.position.set(0.95, -5.75, -0.9);
      fireB1.rotation.set(0, 0.36, 1);
      fireB1.scale.set(0.3, 0.25, 0.2);
      fireB2.name = "fireB2"
      fireB2.position.set(-0.99, -5.75, -1);
      fireB2.rotation.set(0, -10.56, 1);
      fireB2.scale.set(0.3, 0.25, 0.2);
      fireB3.name = "fireB3"
      fireB3.position.set(-0.93, -5.75, 1);
      fireB3.rotation.set(0, 3.75, 1);
      fireB3.scale.set(0.3, 0.25, 0.2);
      fireB4.name = "fireB4"
      fireB4.position.set(1, -5.75, 1);
      fireB4.rotation.set(0, -0.8, 1);
      fireB4.scale.set(0.3, 0.25, 0.2);
  
      fireC1.name = "fireC1"
      fireC1.position.set(0.95, -5.45, -0.9);
      fireC1.rotation.set(0, 0.36, 1);
      fireC1.scale.set(0.3, 0.25, 0.2);
      fireC2.name = "fireC2"
      fireC2.position.set(-0.99, -5.45, -1);
      fireC2.rotation.set(0, -10.56, 1);
      fireC2.scale.set(0.3, 0.25, 0.2);
      fireC3.name = "fireC3"
      fireC3.position.set(-0.93, -5.45, 1);
      fireC3.rotation.set(0, 3.75, 1);
      fireC3.scale.set(0.3, 0.25, 0.2);
      fireC4.name = "fireC4"
      fireC4.position.set(1, -5.45, 1);
      fireC4.rotation.set(0, -0.8, 1);
      fireC4.scale.set(0.3, 0.25, 0.2);
  
      fireD1.name = "fireD1"
      fireD1.position.set(0.95, -5.15, -0.9);
      fireD1.rotation.set(0, 0.36, 1);
      fireD1.scale.set(0.3, 0.25, 0.2);
      fireD2.name = "fireD2"
      fireD2.position.set(-0.99, -5.15, -1);
      fireD2.rotation.set(0, -10.56, 1);
      fireD2.scale.set(0.3, 0.25, 0.2);
      fireD3.name = "fireD3"
      fireD3.position.set(-0.93, -5.15, 1);
      fireD3.rotation.set(0, 3.75, 1);
      fireD3.scale.set(0.3, 0.25, 0.2);
      fireD4.name = "fireD4"
      fireD4.position.set(1, -5.15, 1);
      fireD4.rotation.set(0, -0.8, 1);
      fireD4.scale.set(0.3, 0.25, 0.2);

      fireGroup.add(fireA1, fireA2, fireA3, fireA4)
      fireGroup.add(fireB1, fireB2, fireB3, fireB4)
      fireGroup.add(fireC1, fireC2, fireC3, fireC4)
      fireGroup.add(fireD1, fireD2, fireD3, fireD4)
  
      guoluScene.add(fireGroup)
    //   console.log(guoluScene)
    });
  }
  // 截面点击处理函数
  const handleClick = function (key, e) {
    modelObj[key].forEach((item) => {
      item.visible = !item.visible;
    });
    if (e.currentTarget.classList.length === 1) {
      e.currentTarget.classList.remove("active");
    } else {
      e.currentTarget.classList.add("active");
    }
    
  };
  // 全部关闭或全部开启按钮处理函数
  const handleClickAll = function (e) {
    let isclose = e.currentTarget.getAttribute('isclose')
    let spanArr = e.currentTarget.parentNode.children
    if (isclose === "true") {
      // 全部开启
      for (let index = 0; index < spanArr.length - 2; index++) {
        const span = spanArr[index];
        span.classList.add('active')
      }
      for (let key in modelObj) {
        if (key !== "锅") {
          modelObj[key].forEach((item) => {
            item.visible = true;
          });
        }
      }
      e.currentTarget.setAttribute('isclose', false)
      e.currentTarget.innerText = '全部关闭'
    } else {
      // 全部关闭
      for (let index = 0; index < spanArr.length - 1; index++) {
        const span = spanArr[index];
        span.classList.remove('active')
      }
      for (let key in modelObj) {
        if (key !== "锅") {
          modelObj[key].forEach((item) => {
            item.visible = false;
          });
        }
      }
      e.currentTarget.setAttribute('isclose', true)
      e.currentTarget.innerText = '全部开启'
    }
  }
  
  function gltfModel1() {
    // glb
    loader.load(
      "/huaian02.glb",
      function (gltf) {
        const root = gltf.scene;
        console.log(root);
        guoluScene = gltf.scene;
        // // // 锅炉主体
        const guoluBody = root.children[0].children[12];
        console.log(guoluBody);
        // //创建材质
        function createGradientMaterial() {
          // 自定义顶点着色器代码
          const vertexShader = `
              varying vec3 vPosition;
              void main() {
                  vPosition = position;
                  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
              }
          `;
  
          // 自定义片元着色器代码
          const fragmentShader = `
            uniform vec3 colorStart;
            uniform vec3 colorEnd;
            varying vec3 vPosition;
  
            void main() {
                // 计算渐变系数（从下到上）
                float factor = (vPosition.y + 1.0) / 2.0;
                factor = factor * factor; // 加速度控制
  
                // 计算颜色插值
                vec3 finalColor;
                if (factor < 0.4) {
                  finalColor = mix(colorStart, colorEnd, factor * 3.0);
                } else {
                  finalColor = mix(colorEnd, colorEnd, (factor - 0.4)* 3.0);
                }
  
                // 输出最终颜色
                gl_FragColor = vec4(finalColor, 0.5);
            }
        `;
  
          // 创建自定义材质
          return new THREE.ShaderMaterial({
            uniforms: {
              colorStart: { value: new THREE.Color(0xebda1e) },
              colorEnd: { value: new THREE.Color(0xf89b0f) },
            },
            vertexShader: vertexShader,
            fragmentShader: fragmentShader,
            transparent: true, // 开启透明
          });
        }
        guoluBody.material = createGradientMaterial();
        // 锅炉烟道
        const guoluYandao = root.children[0].children[13];
        //创建材质
        function createGradientMaterial2() {
          // 自定义顶点着色器代码
          const vertexShader = `
              varying vec3 vPosition;
  
              void main() {
                vPosition = position;
                  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
              }
          `;
  
          // 自定义片元着色器代码
          const fragmentShader = `
              uniform vec3 colorStart;
              uniform vec3 colorEnd;
              varying vec3 vPosition;
  
              void main() {
                  // 计算渐变系数（从上到下，先快后慢）
                  float factor = 1.0 - (vPosition.y - 1.8) / 10.0;
                  factor = 1.0 - factor * factor * factor; // 加速度控制
  
                  // 计算颜色插值
                  vec3 finalColor;
                  finalColor = mix(colorStart, colorEnd, factor);
  
                  // 输出最终颜色
                  gl_FragColor = vec4(finalColor, 0.5);
              }  
          `;
  
          return new THREE.ShaderMaterial({
            uniforms: {
              colorStart: { value: new THREE.Color(0xebda1e) },
              colorEnd: { value: new THREE.Color(0xf89b0f) },
            },
            transparent: true, // 开启透明
            vertexShader: vertexShader,
            fragmentShader: fragmentShader,
          });
        }
        guoluYandao.material = createGradientMaterial2();
  
        // 绑定 A层截面
        root.children[0].children.forEach((obj) => {
          const name = JSON.parse(`"${obj.name}"`);
          obj.name = name;
          obj.translateY(-4.6)
          if (!modelObj[name[0]]) modelObj[name[0]] = [];
          modelObj[name[0]].push(obj);
        });
        root.position.y = -4;
        root.position.x = -2;
        scene.add(gltf.scene);
        function animate() {
        requestAnimationFrame(animate);
        root.rotation.y += 0.005; // 每帧围绕 X 轴旋转 0.01 弧度
        renderer.render(scene, camera);
      }
      animate();
      },
  
      function (xhr) {
        const percent = Math.floor((xhr.loaded / xhr.total) * 100); // 计算加载进度百分比
        // console.log(`模型加载进度：${percent}%`);
      }
    );
  }
  
  function renderModel() {
    //渲染
    renderer.setSize(width, height); //设置渲染区尺寸
    renderer.render(scene, camera); //执行渲染操作、指定场景、相机作为参数
    // renderer.setClearColor(0x00ff00); // 设置背景颜色为绿色
    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    // 设置曝光度
    renderer.toneMappingExposure = 1.5; // 适当调整曝光度
  
    controls.minPolarAngle = Math.PI / 4; // 最小极角为 45 度
    controls.maxPolarAngle = Math.PI / 2; // 最大极角为 90 度
  }
  
  function render() {
    renderer.render(scene, camera);
    controls.update();
    TWEEN.update();
    requestAnimationFrame(render);
  }
  
  // 画布跟随窗口变化
  window.onresize = function () {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
  };
  
  // 交互事件
  addEventListener("dblclick", onMouseDblclick, false);
  function onMouseDblclick(event) {
    let intersects = getIntersects(event);
  
    if (intersects.length !== 0 && intersects[0].object instanceof THREE.Mesh) {
      const selectedObject = intersects[0].object;
      let selectedObjects = [];
      selectedObjects.push(selectedObject);
      console.log(selectedObjects);
      // outlinePass.selectedObjects = selectedObjects;
    }
  }
  //获取与射线相交的对象数组
  function getIntersects(event) {
    let rayCaster = new THREE.Raycaster();
    let mouse = new THREE.Vector2();
  
    //通过鼠标点击位置，计算出raycaster所需点的位置，以屏幕为中心点，范围-1到1
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; //这里为什么是-号，没有就无法点中
  
    //通过鼠标点击的位置(二维坐标)和当前相机的矩阵计算出射线位置
    rayCaster.setFromCamera(mouse, camera);
    return rayCaster.intersectObjects(scene.children);
  }
  </script>
  
  <style scoped lang="scss"></style>
  